{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 浮点数转定点数（C++）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "int32_t significand, exponent;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以 `-1.2` 为例，有 $-1.2 = -0.6 \\times 2^1$："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "double double_multiplier = -1.2;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "获取浮点数的尾数和指数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "double significand_d = std::frexp(double_multiplier, &exponent);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-0.6 1"
     ]
    }
   ],
   "source": [
    "std::cout << significand_d << \" \" << exponent;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "符合我们的预期。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将双精度尾数转换为整数尾数，即将其转换为小数点位于第 31 位和第 30 位之间的整数。这是通过将双精度值乘以 $2^{31}$ 然后强制转换为 `int` 类型来实现的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "significand_d = std::round(significand_d * (1ll << 31));\n",
    "auto significand_int64 = static_cast<int64_t>(significand_d);\n",
    "if (significand_int64 == (1ll << 31)) {\n",
    "    significand_int64 /= 2;\n",
    "    ++exponent;\n",
    "  }\n",
    "significand = static_cast<int32_t>(significand_int64);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1288490189"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "significand"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++14",
   "language": "C++14",
   "name": "xcpp14"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
